package com.kgc.scd.controller;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.kgc.scd.bean.Product;
import com.kgc.scd.bean.Seckill;
import com.kgc.scd.bean.SeckillResult;
import com.kgc.scd.contant.CommonConstant;
import com.kgc.scd.mapper.ProductMapper;
import com.kgc.scd.service.SecKillService;
import com.kgc.scd.util.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * @program: com.kgc.scd.controller
 * @author: HarryXzy
 * @create: 2022-06-14 12:03
 * @description: 秒杀controller
 **/
@Slf4j
@RestController
public class SecKillController {

    @Autowired
    private SecKillService secKillService;

    @Autowired(required = false)
    private ProductMapper productMapper;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;


    /**
    * @author: HarryXzy
    * @date: 2022/6/14 13:25
    * @return: java.util.Map<java.lang.String,java.lang.Object>
    * @description: 获取所有可以参加的活动
    */
    @GetMapping("/getAllSecKill")
    public Map<String, Object> getAllSecKill(){

        HashMap<String, Object> map = new HashMap<>();
        List<Object> seckillList = redisUtils.lGet("seckill", 0, -1);
        if(seckillList.size() == 0){
            // redis中没有数据,去数据库中查找
            List<SeckillResult> allSecKills = secKillService.getAllSecKill();
            // 存入redis中
            for (SeckillResult allSecKill : allSecKills) {
                //long l = (allSecKill.getSeckillEndtime().getTime() - allSecKill.getSeckillStarttime().getTime()) / 1000;
                // 将秒杀活动存入redis中
                redisUtils.lSet("seckill",allSecKill,5000);
            }
            map.put("code", CommonConstant.UNIFY_RETURN_SUCCESS_CODE);
            map.put("msg",CommonConstant.UNIFY_RETURN_SUCCESS_MSG);
            map.put("data",allSecKills);
            return map;
        }
        // redis中有数据
        System.out.println("redisyou");
        List<Object> seckill = redisUtils.lGet("seckill", 0, -1);
        ArrayList<SeckillResult> seckillResults = new ArrayList<>();
        for (Object o : seckill) {
            SeckillResult seckillResult = JSON.parseObject(o.toString(), SeckillResult.class);
            seckillResults.add(seckillResult);
        }
        map.put("code", CommonConstant.UNIFY_RETURN_SUCCESS_CODE);
        map.put("msg",CommonConstant.UNIFY_RETURN_SUCCESS_MSG);
        map.put("data",seckillResults);
        return map;
    }

    /**
    * @author: HarryXzy
    * @date: 2022/6/15 09:32
    * @return: java.util.Map<java.lang.String,java.lang.Object>
    * @description: 点击添加通知
    */
    @GetMapping("/needNotifySecKill")
    public Map<String, Object> needNotifySecKill(@RequestParam String userId,
                                                 @RequestParam("secKillid") String secKillid){
        HashMap<String, Object> map = new HashMap<>();
        boolean b = redisUtils.checkFreq("notifyttl"+userId, 4, 30);
        if(!b){
            map.put("code","4444");
            map.put("msg","操作过于频繁，请稍后再试");
            map.put("data","");
            return map;
        }
        // 判断该用户是否已经加入通知
        try {
            if (secKillService.userHaveNotify(userId, secKillid)) {
                map.put("code", 501);
                map.put("msg", "您已完成登记，我们将会在秒杀开始前5分钟通知您！");
                map.put("data", "");
                return map;
            }
            // 判断能否进行通知（秒杀活动时间是否已小于11分钟）
            if (secKillService.canNotify(secKillid)) {
                // 能够通知 添加通知至数据库
                secKillService.addNotify(userId, secKillid);
                // 添加秒杀活动 redis中采用set进行存储（key为秒杀ID，value为用户ID）
                redisTemplate.opsForSet().add("REGI"+secKillid,userId);
                map.put("code", CommonConstant.UNIFY_RETURN_SUCCESS_CODE);
                map.put("msg", CommonConstant.UNIFY_RETURN_SUCCESS_MSG + "秒杀登记成功，我们将在秒杀开始前5分钟通知您！");
                map.put("data", "");
                return map;
            }
            // 判断活动是不是已经开始了
            if (secKillService.secKillHaveEnd(secKillid)) {
                map.put("code", "503");
                map.put("msg", "秒杀活动已经开始，不能进行登记！");
                map.put("data", "");
                return map;
            }
            map.put("code", "502");
            map.put("msg", "很抱歉暂距离秒杀开始已不足5分钟，已关闭秒杀登记通道");
            map.put("data", "");
            return map;
        }catch (Exception e){
            map.put("code", "503");
            map.put("msg", "秒杀活动不存在");
            map.put("data", "");
            return map;
        }
    }


    /**
     * @author: HarryXzy
     * @date: 2022/6/14 13:25
     * @return: java.util.Map<java.lang.String,java.lang.Object>
     * @description: 添加秒杀活动
     */
    @PostMapping("/addSecKill")
    public Map<String, Object> addSecKill(@RequestBody() Seckill seckill){
        HashMap<String, Object> map = new HashMap<>();
        String seckillProid = seckill.getSeckillProid();
        QueryWrapper<Product> wrapper = new QueryWrapper<>();
        wrapper.eq("pro_id",seckillProid);
        if(productMapper.selectOne(wrapper) == null){
            // 商品id不存在
            map.put("code","502");
            map.put("msg","秒杀商品不存在");
            map.put("data","");
            return map;
        }
        if(seckill.getSeckillStarttime().compareTo(seckill.getSeckillEndtime()) != -1){
            // 时间输入有错误
            map.put("code","503");
            map.put("msg","开始或结束时间有错误");
            map.put("data","");
            return map;
        }
        secKillService.addSecKill(seckill);
        map.put("code", CommonConstant.UNIFY_RETURN_SUCCESS_CODE);
        map.put("msg", "秒杀活动添加成功");
        map.put("data","");
        //long l = (seckill.getSeckillEndtime().getTime() - seckill.getSeckillStarttime().getTime()) / 1000;
        // 将秒杀活动封装完整信息存入redis中
        SeckillResult result = secKillService.getSecKillResultById(seckill.getSeckillId());
        redisUtils.lSet("seckill",result,1000);
        return map;
    }



}


